# 锅炉管理,
# 当关闭时，如果保温功能打开，定时器将文度控制在一定范围
from time import sleep

from PyQt5.QtCore import QObject, pyqtSignal, QTimer
# from gpiozero import LED
# from gpiozero.pins.rpigpio import RPiGPIOFactory
from loguru import logger

import Task
from Temperature import Temperature
import Devices
from singleton import singleton

from enum import Enum


def temp_to_angle(temp):
    return 180 - (temp * 180 / 120)


class Hole(object):
    def __init__(self):
        self._occupy = False
        self._id = None

    @property
    def occupy(self):
        return self._occupy

    @occupy.setter
    def occupy(self, p_occupy):
        self._occupy = p_occupy

    @property
    def id(self):
        return self._id

    @id.setter
    def id(self, p_id):
        self._id = p_id


@singleton
class Boiler(QObject):
    ready_temp_upper = 82
    ready_temp_lower = ready_temp_upper - 10

    boiling_temp = 90  # 沸腾的温度，可能需要设置成动态

    is_heat_preservation = False
    is_on = False
    # switch = LED("GPIO3", pin_factory=RPiGPIOFactory())

    # 炉子有几个煮面的洞洞
    holes = [Hole(), Hole()]


    sig_switch = pyqtSignal(bool)
    heat_signal = pyqtSignal(bool)
    temp_signal = pyqtSignal(int)

    def __init__(self):
        # monitor = Monitor(self, 5)
        # monitor.start()
        super().__init__()
        # self.timer = QTimer()
        # self.timer.setInterval(1000)
        # self.timer.timeout.connect(self.update)
        # self.timer.start()
        self.set_temp(0)

    def init(self):
        pass

    # def get_curr_temp(self):
    #     return Temperature().get_temp()

    # 定时调用这个函数，达到温度管理的目的
    # def update(self):
    #     # 控制关闭 和 保温打开
    #     if not self.is_on and self.is_heat_preservation:
    #         curr_temp = self.get_curr_temp()
    #         if curr_temp < self.ready_temp_lower:
    #             self.heat(True)
    #         if curr_temp > self.ready_temp_upper:
    #             self.heat(False)

    def close(self):
        self.set_temp(0)

    def turn(self, status):
        self.is_on = status
        self.heat(status)

    def set_temp(self, temp):
        Devices.servo_write(9, temp_to_angle(temp))

    def set_heat_preservation(self, status):
        # if not status and not self.is_on:
        #     self.turn(False)
        # self.is_heat_preservation = status
        logger.debug(status)
        if status:
            Devices.servo_write(9, temp_to_angle(self.ready_temp_upper))
        else:
            Devices.servo_write(9, temp_to_angle(0))

    def get_heat_preservation(self):
        return self.is_heat_preservation

    def heat(self, state):
        self.sig_switch.emit(state)
        if state:
            self.switch_on()
        else:
            self.switch_off()

    def switch_on(self):
        Devices.servo_write(9, temp_to_angle(95))

    def switch_off(self):
        Devices.servo_write(9, temp_to_angle(40))

    # def set_ready(self):
    #     Devices.servo_write(9, temp_to_angle(90))

    def is_boiling(self):
        return Devices.digital_read(8)
        # return self.get_curr_temp() >= self.boiling_temp
        # return True

    def do_action(self, params):
        self.turn(params["on"])

    def wait_action(self):
        return True
        # return self.wait_for_arrival()

    def is_hole_full(self):
        for hole in self.holes:
            if not hole.occupy:
                return False
        else:
            return True

    def get_one_empty_hole(self):
        for i, hole in enumerate(self.holes):
            if not hole.occupy:
                return True, i

        return False, 0

    def set_hole(self, index, p_occupy, p_id):
        self.holes[index].occupy = p_occupy
        self.holes[index].id = p_id

    def find_pos_by_hold(self, hold):
        positions = [0, 1000]
        return positions[hold]
